import importlib
import os
import sys
import time
from PyQt5.QtCore import QTimer, pyqtSignal, Qt
from PyQt5.QtGui import QKeySequence, QFont, QBrush, QColor
from PyQt5.QtWidgets import QMessageBox, QWidget, QShortcut, QApplication, QPushButton, QListWidgetItem, QSizePolicy
import resources.resource_rc
from serialPort import SerialPortWindow
from serialPort import cm3_pb2

try:
    from windowUI.viewParamUI import Ui_ViewParamWidget
except Exception as e:
    print(e)
    from mainUI import Ui_ViewParamWidget


class ViewParamWindow(Ui_ViewParamWidget, QWidget):
    # 声明带一个字典类型参数的信号
    viewParamSignal = pyqtSignal(dict)  # 主界面的信号用来绑定子界面类的函数方法

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 引入公共程序
        from utils.common import commonProgram
        # 引入配置文件
        self.myConfig = commonProgram.EnableConfigHandler()
        print('ViewParamWindow get config Version', self.myConfig.version)
        # 引入可控串口信息窗口
        commonProgram.EnableSerialPort(winSignal=self.viewParamSignal, RecvSerialData=self.RecvSerialData)

        # 快捷键
        self.screenStatus = 'Normal'
        screenShortcut = QShortcut(QKeySequence(Qt.Key_F11), self)
        screenShortcut.activated.connect(self.WindowSizeFun)
        self.setToolTip('全屏与退出全屏：\n               双击 或者 F11')

        # 初始化测试项
        self.myConfig.passTestItems = set()
        idx = -1
        for item in self.myConfig.testItems:
            compName = item['compName']
            widItem = QListWidgetItem()
            widItem.setText(item['btnName'])
            widItem.setToolTip(compName)
            # 设置字体（字体，字号，颜色）
            # widItem.setFont(QFont('Times', 16, QFont.Bold))
            # 另外一种方法设置颜色（该为红色）
            widItem.setForeground(QBrush(QColor(255, 0, 0)))
            # 设置背景色
            # widItem.setBackground(QBrush(QColor(0, 0, len(self.item_list1)*20)))
            # btnItem = QPushButton(self)
            # btnItem.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
            # btnItem.setObjectName('btn' + compName)
            # btnItem.setText(item['btnName'])
            # btnItem.setStyleSheet("color: rgb(255, 0, 0);")
            self.listTestItems.addItem(widItem)
            idx += 1
        # 连接信号
        self.btnSendResult.clicked.connect(self.SendResultsFun)
        self.btnCleanRecords.clicked.connect(self.CleanRecordsFun)
        self.listTestItems.itemClicked.connect(self.checkItemFun)
        # 全屏
        self.WindowSizeFun()
        # 参数查看界面 展示内容 通过记录
        self.viewAllDataSet = set()
        self.viewDataSet = set()
        self.__reInitFun()

    def __reInitFun(self):
        self.viewDataSet.clear()
        list = cm3_pb2.MsgType.keys()
        self.viewAllDataSet.add(list[2])
        self.viewAllDataSet.add(list[3])
        self.viewAllDataSet.add(list[4])

    def checkItemFun(self, modelIndex):
        for item in self.myConfig.testItems:
            compName = item['compName']
            if modelIndex.toolTip() in compName:
                dictData = {
                    'type': 'Self_to_Main',
                    'data': {'msg_type': 'logic', 'operate': 'switch', 'subject': 'Item',
                             'object': compName}
                }
                self.DataHandleFun(dictData)

    def getListTestItem(self, itemName):
        for i in range(self.listTestItems.count()):
            item = self.listTestItems.item(i)
            # print(item.text(), item.toolTip())
            if item.toolTip() in itemName:
                # print('Found item ', btnItem.objectName())
                # btnItem.setStyleSheet("color: rgb(0, 255, 2);")
                # self.listTestItems.removeItemWidget(self.listTestItems.takeItem(i))
                return item
        print('Not found ', itemName)
        return None

    def SendResultsFun(self):
        dictData = {
            'type': 'Self_to_Main',
            'data': {'msg_type': 'function', 'operate': 'call', 'subject': 'Main', 'object': 'SendResultsFun()'}
        }
        self.DataHandleFun(dictData)

    def CleanRecordsFun(self):
        dictData = {
            'type': 'Self_to_Main',
            'data': {'msg_type': 'function', 'operate': 'call', 'subject': 'Main', 'object': 'CleanRecordsFun()'}
        }
        self.DataHandleFun(dictData)
        for item in self.myConfig.testItems:
            compName = item['compName']
            self.getListTestItem(compName).setForeground(QBrush(QColor(255, 0, 0)))
        self.__reInitFun()

    def RecvSerialData(self, dictData: dict):
        # 用于接收Form2发过来的数据
        # dataStr = dictData.get("data", None)  # num2 就是子界面传递过来的数据
        self.DataHandleFun(dictData)
        for item in self.myConfig.passTestItems:
            self.getListTestItem(item).setForeground(QBrush(QColor(0, 255, 2)))

    def DataHandleFun(self, dataDict: dict):
        typeStr = dataDict.get('type', 'null').strip()
        if typeStr == 'rece_protobuf':
            if len(self.viewAllDataSet ^ self.viewDataSet) <= 0:
                self.myConfig.passTestItems.add('ViewParam')
            self.HandleProtobufFun(dataDict)
        elif typeStr == 'send_protobuf':
            self.viewParamSignal.emit(dataDict)
        elif 'viewParam_to_' in typeStr:
            return
        elif 'Self_to_' in typeStr:
            typeList = typeStr.split('_')
            dataDict['type'] = 'viewParam_to_' + typeList[-1]
            self.viewParamSignal.emit(dataDict)
        elif typeStr == 'statusbar':
            dataStr = dataDict.get('data', '')
            self.textNotice.setText(dataStr)

    def HandleProtobufFun(self, dataDict: dict):
        display = dataDict.get('data', '')
        if display.msg_type == cm3_pb2.Status:
            self.viewDataSet.add('Status')
            if int(display.status.onoff) > 0:
                powerStatus = True
            else:
                powerStatus = False
            self.textVoltage.setText(str(display.status.voltage / 1000))
            self.textCurrent.setText(str(display.status.current / 1000))
            self.textPower.setText(str(display.status.power / 1000))
            self.checkPower.setChecked(powerStatus)
            self.textModuleTemp.setText(str(display.status.module_temp))
            self.textPcbTemp.setText(str(display.status.pcb_temp))
            self.textAngle.setText(str(display.status.gyro / 2 - 100))
            self.sliderLight.setValue(display.status.light)
        elif display.msg_type == cm3_pb2.Version:
            self.viewDataSet.add('Version')
            self.textHardVersion.setText(display.version.hw)
            self.textSoftVersion.setText(display.version.sw)
            self.textBoot.setText(display.version.boot)
        elif display.msg_type == cm3_pb2.DTC:
            self.viewDataSet.add('DTC')
            self.textDTC.setText(display.dtc.prefix + display.dtc.value)

    def WindowSizeFun(self):
        # print(toStatus)
        if self.screenStatus == 'Normal':
            self.showFullScreen()
            self.screenStatus = 'FullScreen'
        else:
            self.showNormal()
            self.screenStatus = 'Normal'


# 程序入口
if __name__ == "__main__":
    ######使用下面的方式一定程度上可以解决界面模糊问题--解决电脑缩放比例问题
    # debain 上面没有这个 ：setHighDpiScaleFactorRoundingPolicy
    # QGuiApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    # QGuiApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    # 在主函数入口之前加入上面的设置即可解决
    # 适应高DPI设备
    # QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    # 解决图片在不同分辨率显示模糊问题
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    # QApplication.setAttribute( Qt.AA_Use96Dpi)
    app = QApplication(sys.argv)
    font = QFont("宋体")
    pointsize = font.pointSize()
    font.setPixelSize(int(pointsize * 90 / 72))
    app.setFont(font)
    # myWin = MyMainWindow()
    mainWindow = ViewParamWindow()
    mainWindow.show()
    sys.exit(app.exec_())
